package com.szfore.util.pdf;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.pdfbox.exceptions.COSVisitorException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.edit.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.graphics.color.PDGamma;
import org.apache.pdfbox.pdmodel.graphics.xobject.PDJpeg;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationMarkup;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationSquareCircle;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationText;

public class PdfUtil {
	
	private static final String savePath = "F://pdf";
	
	public static void main(String[] args) 
	{
		String saveFilePath = savePath + "/远界CRM.pdf";
		try {
			createFrom(saveFilePath, savePath + "/target.pdf");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void createFrom(String sourcePdfPath, String targetPdfPath) throws Exception
	{
		List<BufferedImage> images = readAsImage(sourcePdfPath);
		
		PDDocument tPdf = new PDDocument();
		
		for (int i = 0; i < images.size(); i++) 
		{
			BufferedImage image = images.get(i);
			
			PDPage page = createPageWithImage(tPdf, image, 820, 540);
			
			String annotationContent = "这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，这是笔记，";
			addFreeTextAnnotation(page, annotationContent, 725, 5, 815, 535);
		}
		
		tPdf.save(targetPdfPath);
	}

	
	private static void addFreeTextAnnotation(PDPage page, String annotationContent, int lowerLeftX, int lowerLeftY, int upperRightX, int upperRightY) throws IOException 
	{
		List<PDAnnotation> annotations = page.getAnnotations();
		
		PDAnnotationSquareCircle aSquare = new PDAnnotationSquareCircle( PDAnnotationSquareCircle.SUB_TYPE_FREETEXT);
		aSquare.setContents(annotationContent);
		
		PDRectangle  position = new PDRectangle(); // Reuse the variable, but note it's a new object!
		position.setLowerLeftX(lowerLeftX);  // 1" in from right, 1" wide
		position.setLowerLeftY(lowerLeftY); // 1" height, 3.5" down
		position.setUpperRightX(upperRightX); // 1" in from right
		position.setUpperRightY(upperRightY); // 3.5" down
		aSquare.setRectangle(position);

		annotations.add(aSquare);
	}

	
	private static PDPage createPageWithImage(PDDocument tPdf, BufferedImage image, int pageWidth, int pageHeight)
			throws IOException 
	{
		PDJpeg pdJpg = new PDJpeg(tPdf, image);
		
		PDPage page = new PDPage();
		tPdf.addPage(page);
		
		page.getMediaBox().setLowerLeftX(0);
		page.getMediaBox().setLowerLeftY(0);
		page.getMediaBox().setUpperRightX(pageWidth);
		page.getMediaBox().setUpperRightY(pageHeight);
		
		PDPageContentStream contentStream = new PDPageContentStream(tPdf, page, true, true);
		contentStream.drawXObject(pdJpg, 0, 0, 720, 540);
		contentStream.close();
		return page;
	}

	
	@SuppressWarnings("rawtypes")
	private static List<BufferedImage> readAsImage(String sourcePdfPath)throws IOException 
	{
		PDDocument pdf = PDDocument.load(sourcePdfPath);
		
		List pages = pdf.getDocumentCatalog().getAllPages();
		List<BufferedImage> images = new ArrayList<BufferedImage>();
		
		for (int i = 0; i < pages.size(); i++) 
		{
			PDPage page = (PDPage)pages.get(i);
			BufferedImage image = page.convertToImage();
			images.add(image);
		}
		return images;
	}
	
	public static void addAnnotation(PDPage page, String content)
	{
		PDAnnotationText txtMark = new PDAnnotationText();
		
		float pw = page.getMediaBox().getWidth();
        float ph = page.getMediaBox().getHeight();
        
        PDRectangle position = new PDRectangle();
        position.setLowerLeftX(pw - 100);
        position.setLowerLeftY(ph - 50); // 1" height, 3" down
        position.setUpperRightX(pw - 50); // 1" in, 1" width
        position.setUpperRightY(ph - 25); // 3" down
        txtMark.setRectangle(position);
        
        PDGamma c = new PDGamma();
        c.setG(1);
        
        txtMark.setOpen(true);
        txtMark.setColour(c);
        
        txtMark.setContents(content);
        try {
			page.getAnnotations().add(txtMark);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	
	public static void createPdf(String content, String saveFilePath)
	{
		PDDocument document = new PDDocument();
		PDPage page = new PDPage();
		
		PDAnnotationMarkup anno = new PDAnnotationMarkup();
		anno.setContents("笔记笔记笔记笔记笔记笔记笔记笔记笔记笔记笔记笔记");
		anno.setPage(page);
		
		PDFont font = PDType1Font.HELVETICA_BOLD;

		PDPageContentStream contentStream;
		try {
			contentStream = new PDPageContentStream(document, page);
			contentStream.beginText();
			contentStream.setFont( font, 12 );
			contentStream.moveTextPositionByAmount( 100, 700 );
			contentStream.drawString(content);
			contentStream.endText();

			contentStream.close();

			List<PDAnnotation> annos = new ArrayList<PDAnnotation>();
			annos.add(anno);
			page.setAnnotations(annos);
			
			document.addPage( page );

			
			document.save(saveFilePath);
			document.close();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (COSVisitorException e) {
			e.printStackTrace();
		}
	}
	
	
	public static void createBlankPdf(String saveFilePath) 
	{
		PDDocument document = new PDDocument();
		
		PDPage blankPage = new PDPage();
		document.addPage( blankPage );

		try {
			document.save(saveFilePath);
			document.close();
		} catch (COSVisitorException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
